/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * ObjectGenerator.java
 *
 * Created on Oct 6, 2010, 3:03:02 AM
 */

package com.celephais.objectGenerator;

import com.celephais.objectGenerator.fileGenerators.ClientModelGenerator;
import com.celephais.objectGenerator.fileGenerators.ClientServiceAsyncGenerator;
import com.celephais.objectGenerator.fileGenerators.ClientServiceGenerator;
import com.celephais.objectGenerator.fileGenerators.FileGenerator;
import com.celephais.objectGenerator.fileGenerators.ServerModelGenerator;
import com.celephais.objectGenerator.fileGenerators.ServerServiceGenerator;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JTabbedPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.WindowConstants;

/**
 *
 * @author Eugene Shen
 */
public class ObjectGenerator extends javax.swing.JFrame {

	private static final long serialVersionUID = -4341388541084787388L;

	private static final String SERVER_MODEL_TEMPL_DIR = "templates" + File.separator + "serverModel" + File.separator;

	private ArrayList<FileGenerator> fileGenerators;

    /** Creates new form ObjectGenerator */
    public ObjectGenerator() {
        initComponents();
		additionalInitComponents();
		File indir = new File(SERVER_MODEL_TEMPL_DIR);
		if (indir.exists() && indir.isDirectory()) {
			System.out.println("Indir found!");
		}
		else {
			System.out.println("Indir not found: " + indir.getAbsolutePath());
		}

		// List of file generators.
		fileGenerators = new ArrayList<FileGenerator>();
		fileGenerators.add(new ServerModelGenerator(this));
		fileGenerators.add(new ServerServiceGenerator(this));
		fileGenerators.add(new ClientServiceGenerator(this));
		fileGenerators.add(new ClientServiceAsyncGenerator(this));
		fileGenerators.add(new ClientModelGenerator(this));
		// TODO: Add the remaining generators.
    }

	public ObjectDetailsPanel getDetailsPanel() {
		return detailsPanel;
	}

	public void generateCode() {
		String srcDir = basicInfoPanel.getSourceDir();
		String srcPkgName = basicInfoPanel.getSourcePkgName();
		String objName = basicInfoPanel.getObjName();

		if (!validateObjName(objName)) {
			return;
		}
		else if (!detailsPanel.validateFieldNames()) {
			return;
		}

		File dir = new File(srcDir);
		if ((!dir.exists() && !dir.mkdirs()) || !dir.isDirectory()) {
			popErrorDialog("The path " + srcDir + " is not a valid directory or attempts to create it failed.  Please double check your path.");
			return;
		}

		srcDir = dir.getAbsolutePath();
		String serverDir = srcDir + File.separator + "server";
		File servSvcDir = new File(serverDir + File.separator + "service");
		if ((!servSvcDir.exists() && !servSvcDir.mkdirs()) || !servSvcDir.isDirectory()) {
			popErrorDialog("Unable to create the server-side's Service Directory " + servSvcDir.getAbsolutePath());
			return;
		}

		File servModelDir = new File(serverDir + File.separator + "model");
		if ((!servModelDir.exists() && !servModelDir.mkdirs()) || !servModelDir.isDirectory()) {
			popErrorDialog("Unable to create the server-side's Model Directory " + servModelDir.getAbsolutePath());
			return;
		}

		String clientDir = srcDir + File.separator + "client";
		File clientSvcDir = new File(clientDir + File.separator + "service");
		if ((!clientSvcDir.exists() && !clientSvcDir.mkdirs()) || !clientSvcDir.isDirectory()) {
			popErrorDialog("Unable to create the client-side's Service Directory " + clientSvcDir.getAbsolutePath());
			return;
		}

		File clientModelDir = new File(clientDir + File.separator + "model");
		if ((!clientModelDir.exists() && !clientModelDir.mkdirs()) || !clientModelDir.isDirectory()) {
			popErrorDialog("Unable to create the client-side's Model Directory " + clientModelDir.getAbsolutePath());
			return;
		}

		// Actual code generation.
		for (FileGenerator fg : fileGenerators) {
			if (!fg.generateFile(srcDir, srcPkgName, objName)) {
				return;
			}
		}

		JOptionPane.showMessageDialog(this, "Please see the %readme.txt% file for more details", "Files successfully generated!", JOptionPane.INFORMATION_MESSAGE);
	}

	private boolean validateObjName(String name) {
		if (name.length() == 0) {
			popErrorDialog("Please enter a name for your object.");
			return false;
		}
		else {
			char c = name.charAt(0);
			if (c != '_' && !Character.isLetter(c)) {
				popErrorDialog("The object name must begin with either a letter or a _ (underscore).");
				return false;
			}
			else {
				for (int i=1; i<name.length(); ++i) {
					c = name.charAt(i);
					if (c != '_' && !Character.isLetterOrDigit(c)) {
						popErrorDialog("The object name must only contain letters, digits, or _ (underscore).");
						return false;
					}
				}
			}
		}
		return true;
	}

	private void popErrorDialog(String msg) {
		JOptionPane.showMessageDialog(this, msg, "Cannot Generate Code", JOptionPane.ERROR_MESSAGE);
	}

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        topTabbedPane = new JTabbedPane();
        topMenuBar = new JMenuBar();
        fileMenu = new JMenu();
        Exit = new JMenuItem();
        editMenu = new JMenu();

        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setTitle("Celephais Object Generator");
        setMinimumSize(new Dimension(640, 480));
        setName("Form"); // NOI18N

        topTabbedPane.setName("topTabbedPane"); // NOI18N

        topMenuBar.setName("topMenuBar"); // NOI18N

        fileMenu.setText("File");
        fileMenu.setName("fileMenu"); // NOI18N

//        ActionMap actionMap = Application.getInstance(CelephaisObjectGeneratorApp.class).getContext().getActionMap(ObjectGenerator.class, this);
//        Exit.setAction(actionMap.get("quit")); // NOI18N
        Exit.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				System.exit(0);
			}
        });
        Exit.setMnemonic('x');
        Exit.setText("Exit");
        Exit.setName("Exit"); // NOI18N
        fileMenu.add(Exit);

        topMenuBar.add(fileMenu);

        editMenu.setText("Edit");
        editMenu.setName("editMenu"); // NOI18N
        topMenuBar.add(editMenu);

        setJMenuBar(topMenuBar);

        GroupLayout layout = new GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(Alignment.LEADING)
            .addComponent(topTabbedPane, GroupLayout.DEFAULT_SIZE, 588, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(Alignment.LEADING)
            .addComponent(topTabbedPane, GroupLayout.DEFAULT_SIZE, 424, Short.MAX_VALUE)
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

	private void additionalInitComponents() {
		basicInfoPanel = new BasicInfoPanel(this);
		detailsPanel = new ObjectDetailsPanel();

		topTabbedPane.add("Basic Information", basicInfoPanel);
		topTabbedPane.add("Object Details", detailsPanel);
	}

    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) {
		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (ClassNotFoundException ex) {
			Logger.getLogger(ObjectGenerator.class.getName()).log(Level.SEVERE, null, ex);
		} catch (InstantiationException ex) {
			Logger.getLogger(ObjectGenerator.class.getName()).log(Level.SEVERE, null, ex);
		} catch (IllegalAccessException ex) {
			Logger.getLogger(ObjectGenerator.class.getName()).log(Level.SEVERE, null, ex);
		} catch (UnsupportedLookAndFeelException ex) {
			Logger.getLogger(ObjectGenerator.class.getName()).log(Level.SEVERE, null, ex);
		}
		
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new ObjectGenerator().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private JMenuItem Exit;
    private JMenu editMenu;
    private JMenu fileMenu;
    private JMenuBar topMenuBar;
    private JTabbedPane topTabbedPane;
    // End of variables declaration//GEN-END:variables

	private BasicInfoPanel basicInfoPanel;
	private ObjectDetailsPanel detailsPanel;
}
